﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.Statistics
{
    /// <summary>
    /// This class provides a few methods to approximate a linear function to a data pool 
    /// of plane points by the theorem of linear regression.
    /// </summary>
    [Serializable]
    public class SimpleLinearRegression
    {
        /// <summary>
        /// The regressiondata.
        /// </summary>
        private readonly Point2DCollection data;

        /// <summary>
        /// Initializes a new instance of the <see cref="SimpleLinearRegression"/> class.
        /// </summary>
        /// <param name="data">The regressiondata in form of a Point2DCollection.</param>
        public SimpleLinearRegression(Point2DCollection data)
        {
            if (data == (Point2DCollection) null)
            {
                throw new ArgumentNullException("data");
            }

            this.data = data;
        }

        /// <summary>
        /// Approximates a linear function out of all the regressiondata.
        /// </summary>
        /// <returns>The approximated linear function.</returns>
        public LinearFunction ApproximateLinearFunction()
        {
            double[] xPos = this.data.ExtractXPositionArray();
            double[] yPos = this.data.ExtractYPositionArray();

            double t = Arrays.Avg(xPos);
            double y = Arrays.Avg(yPos);

            xPos = Arrays.Substract(xPos, t);
            yPos = Arrays.Substract(yPos, y);

            double x1 = (Arrays.Sum(Arrays.Multiply(xPos, yPos))) / Arrays.Sum(Arrays.Multiply(xPos, xPos));
            double x0 = y - x1 * t;

            return new LinearFunction(x1, x0);
        }
    }
}